/* необходимый заголовок */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

/*

	базовая форма
	int getopt(int argc, char * const argv[],  const char *optstring);

*/

int main(int argc, char *argv[])
{
	/*
		обычная опция без аргументов обозначается просто буквой
		если после опции должен идти ее аргумент, такую опцию маркируем двоеточием (:)
	*/
	char * options = "i:o:cd";

	int c = -1;

	/* парсим строку аргументов до конца */
	while((c = getopt(argc, argv, options)) != -1)
	{
		/* как видно - возврщается ascii-код опции или -1 если парсинг окончился */
		switch(c)
		{
		case 'i':
			/* аргумент опции помещается в optarg */
			printf("option i, value = %s\n", optarg);
			break;

		case 'o':
			printf("option o, value = %s\n", optarg);
			break;

		case 'c':
			printf("option c\n");
			break;

		case 'd':
			printf("option d\n");
			break;

		/* когда происходит какая-то ошибка возвращается этот символ */
		case '?':
			/* сюда помещается ошибочная опция (неизвестная или с пропущенным аргументом) */
			switch(optopt)
			{
				/**/
				case 'i':
				case 'o':
					printf("missing option argument for %c\n", optopt);
					break;

				default:
					printf("unknown argument %c\n", optopt);
					break;
			}		

			return 0;	/* смысла парсить после ошибки уже никакого нет */	
			break;

		/* на самом деле сюда никогда не должны попасть */
		default:
			printf("err : unknown argument %c\n", c);
			abort();
		}
	}

	return 0;

}